package com.motong.gongdan.service;

import cn.hutool.extra.qrcode.QrCodeUtil;
import com.alibaba.excel.util.IoUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.motong.gongdan.config.ResponseData;
import com.motong.gongdan.entity.*;
import com.motong.gongdan.mapper.ProcessesMapper;
import com.motong.gongdan.util.*;
import com.motong.gongdan.vo.system.CustomField.ColumnsConfigure;
import com.motong.gongdan.vo.system.CustomField.ColumnsConfigureList;
import com.motong.gongdan.vo.system.otherVo.CustomFieldVo;
import com.motong.gongdan.vo.system.otherVo.ProcessRoteProcessVo;
import com.motong.gongdan.vo.system.processSop.CollectionDataVo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ProcessesService extends ServiceImpl<ProcessesMapper, Processes> {

    @Value("${qRFilePrefix}")
    private String qRPrefix;

    @Resource
    UserService userService;
    @Resource
    DepartmentsService departmentsService;
    @Resource
    ProcessesService processesService;
    @Resource
    ProcessRouteService processRouteService;
    @Resource
    CustomNumberService customNumberService;
    @Resource
    CustomFieldService customFieldService;
    @Resource
    ProcessSopService processSopService;
    @Resource
    BadProductService badProductService;
    @Resource
    MongoTemplate mongoTemplate;

    @Resource
    private ProcessesMapper processesMapper;

    public ResponseData<String> getStringResponseData(Processes vo) {
        boolean isUpdate = Objects.nonNull(vo.getId());
        if (StringUtil.isBlank(vo.getCode())) {
            String code = customNumberService.generator(9);
            if (code.equals("fail")) {
                return ResponseData.fail(500, "流水号已用完，请手动输入");
            }
            vo.setCode(code);
        }
        if (vo.getId() == null) {
            Processes p = processesService.getOne(new QueryWrapper<Processes>().eq("name", vo.getName()));
            if (p != null) {
                return ResponseData.fail(500, "工序名称重复");
            }
            if (StringUtil.isNotBlank(vo.getCode())) {
                Processes p1 = processesService.getOne(new QueryWrapper<Processes>().eq("code", vo.getCode()));
                if (p1 != null) {
                    return ResponseData.fail(500, "工序编号重复");
                }
            }
        }
        vo.setPermissionsName("");
        if (StringUtil.isNotBlank(vo.getPermissions()) && vo.getPermissions().equals("-1")) {
            vo.setPermissionsName("所有人");
            List<User> userList = userService.list(new QueryWrapper<User>().eq("state", 0).eq("factory_id", LoginUtil.getLoginUserFactory()));
            vo.setPermissions(userList.stream().map(User::getId).map(m -> m + "").collect(Collectors.joining(",")));
        } else if (StringUtil.isBlank(vo.getPermissions())) {
            vo.setPermissions("");
            List<String> strings = new ArrayList<>();
            if (StringUtil.isNotBlank(vo.getDepIds())) {
                List<Departments> list = departmentsService.listByIds(Arrays.asList(vo.getDepIds().split(",")));
                if (!CollectionUtils.isEmpty(list)) {
                    list.forEach(l -> {
                        vo.setPermissionsName(vo.getPermissionsName() + l.getName() + ",");
                        if (l.getIds() != null && StringUtil.isNotBlank(l.getIds())) {
                            strings.addAll(Arrays.asList(l.getIds().split(",")));
                        }
                    });
                }
                vo.setPermissionsDep(vo.getDepIds());
            }
            if (StringUtil.isNotBlank(vo.getUserIds())) {
                List<User> userList = userService.listByIds(Arrays.asList(vo.getUserIds().split(",")));
                userList.forEach(u -> {
                    vo.setPermissionsName(vo.getPermissionsName() + u.getName() + ",");
                    strings.add(u.getId().toString());
                });
            }
            vo.setPermissions(strings.stream().distinct().collect(Collectors.joining(",")));
        }
        if (vo.getId() == null) {
            ProcessSop ps = new ProcessSop();
            ps.setProcessCode(vo.getCode());
            ps.setProcessName(vo.getName());
            ps.setState(1);
            ps.setBeginZone("开始生产任务");
            ps.setEndZone("结束生产任务");
            processSopService.save(ps);
        }
        if (!CollectionUtils.isEmpty(vo.getVos())) {
            if (vo.getVos().stream().map(CollectionDataVo::getName).distinct().count() != vo.getVos().size()) {
                return ResponseData.fail(500, "采集数据名称不允许重复");
            }
            vo.setCollectionData(JSONArray.parseArray(JSON.toJSONString(vo.getVos())).toJSONString());
        } else {
            vo.setCollectionData("");
        }
        if (!CollectionUtils.isEmpty(vo.getCustomFieldVos())) {
            vo.setOther(customFieldService.handleObjectCreateOrEdit(vo.getCustomFieldVos()).toJSONString());
        }
        processesService.saveOrUpdate(vo);
        if (!isUpdate) {
            String fileName = qRPrefix + System.currentTimeMillis() + ".jpg";
            QrCodeUtil.generate(String.format("processId=%d", vo.getId()), 300, 300, cn.hutool.core.io.FileUtil.file(fileName));
            vo.setQr(fileName);
        }
        if (CollectionUtils.isEmpty(vo.getCustomFieldVos())) {
            MongoUtils.deleteById(vo.getId(), mongoTemplate, "processes");
            processesService.updateById(vo);
        }
        if (vo.getId() != null) {
            if (!CollectionUtils.isEmpty(vo.getCustomFieldVos())) {
                Processes processes = new Processes();
                processes.setCustomFieldMess(JSONArray.parseArray(vo.getOther()));
                processes.setCode(vo.getCode());
                processes.setId(vo.getId());
                mongoTemplate.save(processes);
            }
            Processes p = processesService.getById(vo.getId());
            List<ProcessRoute> prList = processRouteService.list();
            if (!CollectionUtils.isEmpty(prList)) {
                prList.forEach(pr -> {
                    if (StringUtil.isNotBlank(pr.getProcessList())) {
                        List<ProcessRoteProcessVo> listNew = new ArrayList<>();
                        List<ProcessRoteProcessVo> list = JSONArray.parseArray(pr.getProcessList()).toJavaList(ProcessRoteProcessVo.class);
                        list.forEach(l -> {
                            if (l.getId().equals(p.getId())) {
                                l.setCode(p.getCode());
                                l.setName(p.getName());
                                l.setRate(p.getRate());
                            }
                            listNew.add(l);
                        });
                        JSONArray ja = JSONArray.parseArray(JSON.toJSONString(listNew));
                        pr.setProcessList(ja.toJSONString());
                        processRouteService.updateById(pr);
                    }
                });
            }
        }
        //重置首页工序设置
        List<User> userList = userService.list(new QueryWrapper<User>().eq("state", 0).eq("factory_id", LoginUtil.getLoginUserFactory()));
        userList.forEach(i -> RedisUtil.del("home:pmSet:" + i.getId()));
        return ResponseData.success("success");
    }


    public void handleImport(MultipartFile file, Integer type) throws IOException {
        byte[] stream = IoUtils.toByteArray(file.getInputStream());
        List<Map<String, String>> allDataList = EasyExcelImportUtils.parseExcelToData(stream, 2, "工序编号");
        // 空值导入日志
        userService.importBlankExcel(allDataList, "process");

        List<ColumnsConfigureList> allList = userService.handleDefault();
        Map<String, Integer> dataMap = new HashMap<>();
        List<Map<String, String>> failList = new ArrayList<>();
        int a = 0;
        int b = 0;
        List<ColumnsConfigure> defaultColumns = customFieldService.handleImportDefault("processes");
        if (allList.stream().filter(f -> f.getType().equals("processes")).findAny().orElse(null) != null) {
            List<ColumnsConfigure> list = allList.stream().filter(f -> f.getType().equals("processes")).findAny().orElse(null).getColumns();
            String depS = "";
            for (Map<String, String> s : allDataList) {
                Map<String, String> failMap = new HashMap<>();
                Processes processes = new Processes();
                List<CustomFieldVo> vos = new ArrayList<>();
                //表头
                List<String> keyList = new ArrayList<>(s.keySet());
                if (!defaultColumns.stream().filter(f -> f.getChineseName().equals(keyList.get(0))).findAny().isPresent()) {
                    failMap.put("失败原因", "模版读取错误");
                    failList.add(failMap);
                    b++;
                    break;
                }
                int flag = 0;
                for (int i = 0; i < keyList.size() && flag == 0; i++) {
                    if (i >= list.size()) {
                        CustomField cf = customFieldService.getOne(new QueryWrapper<CustomField>().eq("field_ascription", "processes").eq("chinese_name", keyList.get(i)));
                        CustomFieldVo vo = new CustomFieldVo();
                        vo.setCustomFieldId(cf.getId());
                        vo.setValue(s.get(keyList.get(i)));
                        vos.add(vo);
                    } else {
                        switch (i) {
                            case 0:
                                if (StringUtil.isNotBlank(s.get(keyList.get(i)))) {
                                    Processes old = processesService.getOne(new QueryWrapper<Processes>().eq("code", s.get(keyList.get(i))));
                                    if (old == null) {
                                        processes.setCode(s.get(keyList.get(i)));
                                    } else if (old != null && type == 1) {
                                        processes = old;
                                    } else {
                                        failMap.put("失败原因", "已存在相同工序编号");
                                        failMap.put("编号", s.get(keyList.get(i)));
                                        failMap.put("名称", s.get(keyList.get(i + 1)));
                                        failMap.put("报工权限", s.get(keyList.get(i + 2)));
                                        failMap.put("报工数配比", s.get(keyList.get(i + 3)));
                                        failMap.put("不良品分类列表", s.get(keyList.get(i + 4)));
                                        failList.add(failMap);
                                        b++;
                                        flag = 1;
                                        break;
                                    }
                                } else {
                                    String code = customNumberService.generator(9);
                                    if (code.equals("fail")) {
                                        failMap.put("失败原因", "流水号已用完，请手动输入");
                                        failMap.put("编号", "-");
                                        failMap.put("名称", "-");
                                        failMap.put("报工权限", "-");
                                        failMap.put("报工数配比", "-");
                                        failMap.put("不良品分类列表", "-");
                                        failList.add(failMap);
                                        b++;
                                        flag = 1;
                                        break;
                                    }
                                    processes.setCode(code);
                                }
                                continue;
                            case 1:
                                if (StringUtil.isBlank(s.get(keyList.get(i)))) {
                                    failMap.put("失败原因", "名称不能为空");
                                    failList.add(failMap);
                                    b++;
                                    flag = 1;
                                    break;
                                } else {
                                    processes.setName(s.get(keyList.get(i)));
                                }
                                continue;
                            case 2:
                                String permissions = "";
                                if (StringUtil.isNotBlank(s.get(keyList.get(i)))) {
                                    processes.setPermissionsName("");
                                    String importPermissions = s.get(keyList.get(i));
                                    if (s.get(keyList.get(i)).contains("<")) {
                                        List<String> strings = new ArrayList<>();
                                        importPermissions = s.get(keyList.get(i)).replace("<", "").replace(">", ",");
                                        List<Departments> dep = departmentsService.list(new QueryWrapper<Departments>().in("name", Arrays.asList(importPermissions.split(","))));
                                        Processes finalProcesses = processes;
                                        dep.forEach(l -> {
                                            finalProcesses.setPermissionsName(finalProcesses.getPermissionsName() + l.getName() + ",");
                                            if (l.getIds() != null && StringUtil.isNotBlank(l.getIds())) {
                                                strings.addAll(Arrays.asList(l.getIds().split(",")));
                                            }
                                        });
                                        processes = finalProcesses;
                                        permissions = strings.stream().collect(Collectors.joining(","));
                                    } else {
                                        List<String> nameList = Arrays.asList(importPermissions.split(","));
                                        List<Integer> idList = userService.getBaseMapper().selectIdsByNameList(nameList);
                                        permissions = StringUtils.join(idList.toArray(), ",");
                                        processes.setPermissionsName(nameList.stream().collect(Collectors.joining(",")));
                                    }
                                } else {
                                    List<User> userList = userService.list(new QueryWrapper<User>().eq("factory_id", LoginUtil.getLoginUserFactory()));
                                    permissions = userList.stream().map(User::getId).map(String::valueOf).collect(Collectors.joining(","));
                                    processes.setPermissionsName("所有人");
                                }
                                processes.setPermissions(permissions);
                                continue;
                            case 3:
                                if (StringUtil.isNotBlank(s.get(keyList.get(i)))) {
                                    processes.setRate(BigDecimal.valueOf(Double.parseDouble(s.get(keyList.get(i)))));
                                }
                                continue;
                            case 4:
                                if (type == 0 && StringUtil.isBlank(s.get(keyList.get(i)))) {
                                    failMap.put("失败原因", "不良品项不能为空");
                                    failList.add(failMap);
                                    b++;
                                    flag = 1;
                                    break;
                                }
                                if (StringUtil.isNotBlank(s.get(keyList.get(i)))) {
                                    List<String> badList = Arrays.asList(s.get(keyList.get(i)).split(","));
                                    List<Integer> idList = badProductService.getBaseMapper().selectIdsByNameList(badList);
                                    if (!CollectionUtils.isEmpty(idList)) {
                                        String badProduct = StringUtils.join(idList.toArray(), ",");
                                        processes.setBadProduct(badProduct);
                                    }
                                }
                        }
                    }
                }
                if (flag == 0) {
                    if (!CollectionUtils.isEmpty(vos)) {
                        processes.setOther(customFieldService.handleObjectCreateOrEdit(vos).toJSONString());
                    }
                    if (StringUtil.isNotBlank(processes.getCode())) {
                        boolean result = processesService.saveOrUpdate(processes);
                        if (result) {
                            a++;
                        }
                    } else {
                        b++;
                    }
                }
            }
            userService.importLog(LoginUtil.getLoginAccount(), allDataList.size(), OwnUtil.getImportLogDataMap(dataMap, a, b, type), "process", failList);
        }
    }

    // 根据任务id获取工序信息
    public Processes getByMissionId(Integer missionId) {
        return this.processesMapper.getByMissionId(missionId);
    }

    /**
     * 根据用户id获取拥有权限的所有工序
     *
     * @param userId 用户id
     */
    public List<Processes> getPerByUserId(Integer userId) {
        return Optional.ofNullable(this.getBaseMapper().getByUserId(userId)).orElse(Collections.emptyList());
    }
}
